package com.ymx.darling.bean.entity;

import com.ymx.darling.util.StringUtil;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 保存表名及其别名
 * @author 爱Java的小于
 */
public class TableAlias {
    private static final Map<String, TableAlias> tableAliasMap = new ConcurrentHashMap<>();
    private final String schemaName;
    private final String taleName;
    private final String aliasName;

    private TableAlias(String schemaName, String taleName, String aliasName) {
        this.schemaName = schemaName;
        this.taleName = taleName;
        this.aliasName = aliasName;
    }

    public boolean hasAlias() {
        return StringUtil.isNoNull(this.aliasName);
    }

    public String getAliasName() {
        return aliasName;
    }

    public String getTableName() {
        return taleName;
    }

    public String getSchemaName() {
        return schemaName;
    }

    /**
     * 从字符串中提取表名和别名
     * @param strContext 待提取的字符串
     * @return TableAlias
     */
    public static TableAlias splitTableAndAlias(String strContext) {
        if (StringUtil.isNull(strContext)) {
            return new TableAlias("", strContext, "");

        } else {
            return tableAliasMap.computeIfAbsent(strContext, context -> {
                // 定义正则表达式模式，匹配 "表名 as 别名" 或 "表名 别名" 的所有大小写组合
                Pattern pattern = Pattern.compile("(\\w+)\\s+(?:as|AS|As|aS)\\s+(\\w+)|(\\w+)\\s+(\\w+)");
                TableAlias tableAlias = splitTableAndAlias(strContext, pattern);
                // 根据'.'分解数据库或schema等表前缀名称
                String[] schemaAndTableName = splitSchemaAndTableName(tableAlias.getTableName());
                if (schemaAndTableName.length == 2) {
                    return new TableAlias(schemaAndTableName[0], schemaAndTableName[1], tableAlias.getAliasName());
                } else {
                    return tableAlias;
                }
            });
        }
    }


    /**
     * 获取数据库或schema等表前缀名称
     * @param input 表名
     * @return String[] 返回跟个后的数组 大小为1表示无schema前缀 为2表示有schema前缀
     */
    private static String[] splitSchemaAndTableName(String input) {
        int lastDotIndex = input.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return new String[]{input};
        }
        return new String[]{
                input.substring(0, lastDotIndex),
                input.substring(lastDotIndex + 1)
        };
    }


    /**
     * 将表名根据AS 拆分成TableAlia并返回
     * @param strContext 表名
     * @param pattern 正则匹配 AS
     * @return TableAlias
     */
    private static TableAlias splitTableAndAlias(String strContext, Pattern pattern) {
        Matcher matcher = pattern.matcher(strContext.trim());

        TableAlias tableAlias;
        if (matcher.matches()) {
            // 提取表名和别名
            String tableName = matcher.group(1) != null ? matcher.group(1) : matcher.group(3);
            String alias = matcher.group(2) != null ? matcher.group(2) : matcher.group(4);
            tableAlias = new TableAlias("", tableName.trim(), alias.trim());
        } else {
            // 如果没有匹配到，将待提取的字符串本身作为表名返回
            tableAlias = new TableAlias("", strContext, "");
        }
        return tableAlias;
    }

    @Override
    public String toString() {
        return "TableAlias{" +
                "taleName='" + taleName + '\'' +
                ", alisName='" + aliasName + '\'' +
                '}';
    }
}
